package com.qcq.wecheck.controller;


import com.qcq.wecheck.dto.ScheduleDto;
import com.qcq.wecheck.entity.Schedule;
import com.qcq.wecheck.entity.User;
import com.qcq.wecheck.result.CommonResult;
import com.qcq.wecheck.schedule.IoSchedule;
import com.qcq.wecheck.service.ScheduleService;
import com.qcq.wecheck.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 签到表 前端控制器
 * </p>
 *
 * @author O
 * @since 2018-09-19
 */
@RestController
@RequestMapping("/schedule")
@Slf4j
public class ScheduleController {
	@Resource
	private ScheduleService scheduleService;
	@Resource
	private IoSchedule ioSchedule;
	@Resource
	private UserService userService;


	/**
	 * 根据id获取考勤表
	 */
	@GetMapping
	public CommonResult get(@RequestParam("id") Long id) {
		Schedule schedule = scheduleService.selectById(id);
		if (schedule != null) {
			List<Schedule> schedules = new ArrayList<>(1);
			schedules.add(schedule);
			try {
				return CommonResult.success(setMemberCountAndCreator(schedules).get(0));
			} catch (Exception e) {
				log.error("设置vo时出错: {}", e.getMessage());
				return CommonResult.failure("内部错误");
			}
		}
		return CommonResult.failure("考勤表不存在");
	}

	/**
	 * 执行刷新背景图片的url
	 */
	@PostMapping("/refreshUrl")
	public CommonResult refreshUrl() {
		ioSchedule.refreshUrl();
		return CommonResult.success();
	}

	/**
	 * 添加考勤表
	 *
	 * @param schedule 考勤表
	 */
	@PostMapping
	public CommonResult add(@Validated Schedule schedule, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return CommonResult.failure(bindingResult.getFieldError().getDefaultMessage());
		}
		LocalDate start = schedule.getStartDate();
		LocalDate end = schedule.getEndDate();
		if (start.plusMonths(1L).isBefore(end)) {
			return CommonResult.failure("最多只能选择一个月");
		}

		if (scheduleService.hasKeyword(schedule)) {
			return CommonResult.failure("口令已存在, 请输入其它口令");
		}

		if (scheduleService.addOne(schedule)) {
			return CommonResult.success();
		}
		return CommonResult.failure();
	}

	/**
	 * 修改考勤表,条件修改
	 *
	 * @param schedule 考勤表
	 */
	@PutMapping
	public CommonResult update(Schedule schedule) {
		if (schedule.getCreatorId() == null) {
			return CommonResult.failure("openId不能为空");
		}
		if (schedule.getKeywordTag() != null && schedule.getKeyword() != null) {
			if (scheduleService.hasKeyword(schedule)) {
				//口令没有更改,相当于发送过来的口令等于数据库自己表的口令
				boolean keywordEqualsOwn = scheduleService.selectById(schedule.getId()).getKeyword().equals(schedule.getKeyword());
				if (keywordEqualsOwn) {
					scheduleService.updateById(schedule);
				} else {
					return CommonResult.failure("口令已存在, 请输入其它口令");
				}
			} else {
				scheduleService.updateById(schedule);
			}
		}
		return CommonResult.success();
	}

	/**
	 * 分页获取本人创建的考勤表
	 */
	@GetMapping("/own")
	public CommonResult getOwn(@RequestParam("openId") String openId,
	                           @RequestParam("pageNo") Integer pageNo,
	                           @RequestParam("pageSize") Integer pageSize) {
		List<ScheduleDto> vos = new ArrayList<>(pageSize);
		try {
			List<Schedule> schedules = scheduleService.getOwn(openId, pageNo, pageSize);
			if (schedules != null) {
				vos = setMemberCountAndCreator(schedules);
				//倒序输出
				Collections.reverse(vos);
			}
			return CommonResult.success(vos);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return CommonResult.failure();
	}

	/**
	 * 根据签到表id和指定日期获取该签到表某天签到的人员列表
	 */
	@GetMapping("/memberEngaged/specifiedDate")
	public CommonResult memberEngagedOnSpecifiedDate(@RequestParam("id") Long id,
	                                                 @RequestParam("date") String date) {
		return CommonResult.success(scheduleService.getMember(id, date));
	}

	/**
	 * 根据id获取参与该考勤表的人数
	 */
	@GetMapping("/memberCount")
	public CommonResult memberCount(@RequestParam("id") Long id) {
		return CommonResult.success(scheduleService.getMember(id, null).size());
	}

	/**
	 * 根据签到表id获取参加签到的所有人的列表
	 */
	@GetMapping("/memberEngaged")
	public CommonResult memberEngaged(@RequestParam("id") Long id) {
		return CommonResult.success(scheduleService.getMember(id, null));
	}

	/**
	 * 分页获取本人参与的考勤表
	 */
	@GetMapping("/engaged")
	public CommonResult getEngaged(@RequestParam("openId") String openId,
	                               @RequestParam("pageNo") Integer pageNo,
	                               @RequestParam("pageSize") Integer pageSize) {
		List<ScheduleDto> vos = new ArrayList<>(pageSize);
		try {
			List<Schedule> schedules = scheduleService.getEngaged(openId, pageNo, pageSize);
			if (schedules != null) {
				vos = setMemberCountAndCreator(schedules);
				Collections.reverse(vos);
			}
			return CommonResult.success(vos);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return CommonResult.failure();
	}

	/**
	 * 根据签到表id和指定日期获取该签到表某天签到的人数
	 */
	@GetMapping("/memberCount/specifiedDate")
	public CommonResult memberCountOnSpecifiedDate(@RequestParam("id") Long id,
	                                               @RequestParam("date") String date) {
		return CommonResult.success(scheduleService.getMember(id, date).size());
	}

	/**
	 * 根据口令获取考勤表
	 */
	@GetMapping("/keyword")
	public CommonResult getByKeyword(@RequestParam("keyword") String keyword) {
		return CommonResult.success(scheduleService.selectByKeyword(keyword));
	}
	@DeleteMapping
	public CommonResult delete(@RequestParam("id") Long id) {
		boolean success = scheduleService.deleteById(id);
		return success ? CommonResult.success() : CommonResult.failure();
	}

	private List<ScheduleDto> setMemberCountAndCreator(List<Schedule> schedules) throws Exception {
		try {
			return schedules
					.parallelStream()
					.map(schedule -> {
						ScheduleDto vo = new ScheduleDto();
						Integer memberCount = scheduleService.getMember(schedule.getId(), null).size();
						User creator = userService.selectById(schedule.getCreatorId());
						return vo
								.setSchedule(schedule)
								.setMemberCount(memberCount)
								.setCreator(creator);
					})
					.collect(Collectors.toList());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception();
		}
	}
}